﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;

using GalaSoft.MvvmLight.Command;

using NetBay.Core.BusinessEntities;

using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Framework.Pages;
using Rio.Manager.Application.Model;
using Rio.Manager.Application.ViewModel.BaseClass;

using VersioningModel = NetBay.Core.BusinessEntities.Versioning.VersioningModel;

using VersionType = NetBay.Core.BusinessEntities.Versioning.VersionType;

#region Header

//using Rio.Framework.WCFService.RioWcfServices;

#endregion Header

namespace Rio.Manager.Application.ViewModel.FolderTypeAdministration
{
    /// <summary>
    /// Versioning managment 
    /// </summary>
    public class VersioningModelTabViewModel : TabViewModelBase
    {
        #region Fields

        private string _ApprobalOptionLabel;
        private long _ApprovalWkfID;
        private bool _ButtonValideIsEnable = false;
        private string _DescriptionLabel;
        private string _folderTypeLabel;
        private bool _isUpDownVersionMajorEnabled = false;
        private bool _isUpDownVersionMinorEnabled = false;
        private string _lastMajorMinorVersionsSaved;
        private string _lastMajorVersionsSaved;
        private int _MaxMajorVersions = 1;
        private int _MaxMinorVersions = 1;
        private ObservableCollection<DisplayVersionType> _models = new ObservableCollection<DisplayVersionType>();
        private string _organizationLabel;
        private DisplayVersionType _selectedDisplayVersionType = new DisplayVersionType();
        private VersioningModel _selectedModel = new VersioningModel();
        private VersionType _SelectedModelType = VersionType.None;
        private string _StorageSpaceLabel;
        private bool _UseApprobalOption;
        private string _VersionModelLabel;

        #endregion Fields

        #region Constructors

        public VersioningModelTabViewModel()
            : base()
        {
            CanCloseTab = true;
            TabIcon = new Uri("/Rio.Manager.Application;component/Assets/Images/apply_version_model.png", UriKind.Relative);
        }

        #endregion Constructors

        #region Properties

        public string ApprobalOptionLabel
        {
            get { return _ApprobalOptionLabel; }
            set
            {
                _ApprobalOptionLabel = value;
                RaisePropertyChanged("ApprobalOptionLabel");
            }
        }

        /// <summary>
        /// Approbal workflow identifier
        /// </summary>
        public long ApprovalWkfID
        {
            get { return _ApprovalWkfID; }
            set
            {
                _ApprovalWkfID = value;
                RaisePropertyChanged("ApprovalWkfID");
            }
        }

        /// <summary>
        /// Set button valid to Enabled
        /// </summary>
        public bool ButtonValideIsEnable
        {
            get { return _ButtonValideIsEnable; }
            set
            {
                _ButtonValideIsEnable = value;
                RaisePropertyChanged("ButtonValideIsEnable");
            }
        }

        public RelayCommand CreateModelCommand
        {
            get;
            private set;
        }

        /// <summary>
        /// Set or get the description text
        /// </summary>
        public string DescriptionLabel
        {
            get { return _DescriptionLabel; }
            set
            {
                _DescriptionLabel = value;
                RaisePropertyChanged("DescriptionLabel");
            }
        }

        public string FolderTypeLabel
        {
            get { return _folderTypeLabel; }
            set
            {
                _folderTypeLabel = value;
                RaisePropertyChanged("FolderTypeLabel");
            }
        }

        public RelayCommand InitializationCommand
        {
            get;
            set;
        }

        /// <summary>
        /// Change UpDownVersionMajor accessibility
        /// </summary>
        public bool IsUpDownVersionMajorEnabled
        {
            get { return _isUpDownVersionMajorEnabled; }
            set
            {
                _isUpDownVersionMajorEnabled = value;
                RaisePropertyChanged("IsUpDownVersionMajorEnabled");
            }
        }

        /// <summary>
        /// Change UpDownVersionMinor accessibility
        /// </summary>
        public bool IsUpDownVersionMinorEnabled
        {
            get { return _isUpDownVersionMinorEnabled; }
            set
            {
                _isUpDownVersionMinorEnabled = value;
                RaisePropertyChanged("IsUpDownVersionMinorEnabled");
            }
        }

        public string LastMajorMinorVersionsSaved
        {
            get { return _lastMajorMinorVersionsSaved; }
            set
            {
                _lastMajorMinorVersionsSaved = value;
                RaisePropertyChanged("LastMajorMinorVersionsSaved");
            }
        }

        public string LastMajorVersionsSaved
        {
            get { return _lastMajorVersionsSaved; }
            set
            {
                _lastMajorVersionsSaved = value;
                RaisePropertyChanged("LastMajorVersionsSaved");
            }
        }

        /// <summary>
        /// Get or Set the maximum of major versions
        /// </summary>
        public int MaxMajorVersions
        {
            get { return _MaxMajorVersions; }
            set
            {
                _MaxMajorVersions = value;
                RaisePropertyChanged("MaxMajorVersions");
            }
        }

        /// <summary>
        /// Get or Set the maximum of minor versions
        /// </summary>
        public int MaxMinorVersions
        {
            get { return _MaxMinorVersions; }
            set
            {
                _MaxMinorVersions = value;
                RaisePropertyChanged("MaxMinorVersions");
            }
        }

        /// <summary>
        /// List of models to display in the combobox model
        /// </summary>
        public ObservableCollection<DisplayVersionType> Models
        {
            get { return _models; }
            set
            {
                _models = value;
                RaisePropertyChanged("Models");
            }
        }

        public string OrganizationLabel
        {
            get { return _organizationLabel; }
            set
            {
                _organizationLabel = value;
                RaisePropertyChanged("OrganizationLabel");
            }
        }

        /// <summary>
        /// Gets or sets the type of the selected display version.
        /// </summary>
        /// <value>
        /// The type of the selected display version.
        /// </value>
        public DisplayVersionType SelectedDisplayVersionType
        {
            get { return _selectedDisplayVersionType; }
            set
            {
                if (value != null)
                {
                    _selectedDisplayVersionType = value;

                    ChangeLabelDescription();
                    CreateModelCommand.RaiseCanExecuteChanged();

                    RaisePropertyChanged("SelectedDisplayVersionType");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public override FolderType SelectedFolderType
        {
            get
            {
                return base.SelectedFolderType;
            }
            set
            {
                base.SelectedFolderType = value;
                GetModel();
                CreateModelCommand.RaiseCanExecuteChanged();

                RaisePropertyChanged("SelectedFolderType");
            }
        }

        /// <summary>
        /// Curent selected model definition
        /// </summary>
        public VersioningModel SelectedModel
        {
            get { return _selectedModel; }
            set
            {
                _selectedModel = value;
                RaisePropertyChanged("SelectedModel");
            }
        }

        /// <summary>
        /// Selected Organization identifier
        /// </summary>
        /// 
        public override Organization SelectedOrganization
        {
            get
            {
                return base.SelectedOrganization;
            }
            set
            {
                base.SelectedOrganization = value;

                ClearModelValue();

                RaisePropertyChanged("SelectedOrganization");
            }
        }

        public string StorageSpaceLabel
        {
            get { return _StorageSpaceLabel; }
            set
            {
                _StorageSpaceLabel = value;
                RaisePropertyChanged("StorageSpaceLabel");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [use approbal option].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [use approbal option]; otherwise, <c>false</c>.
        /// </value>
        public bool UseApprobalOption
        {
            get { return _UseApprobalOption; }
            set
            {
                _UseApprobalOption = value;
                RaisePropertyChanged("UseApprobalOption");
            }
        }

        public string VersionModelLabel
        {
            get { return _VersionModelLabel; }
            set
            {
                _VersionModelLabel = value;
                RaisePropertyChanged("VersionModelLabel");
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Inits the commands.
        /// </summary>
        public override void InitCommands()
        {
            CreateModelCommand = new RelayCommand(CreateModel, CanCommitChanges);
            InitializationCommand = new RelayCommand(Initialization);
        }

        /// <summary>
        /// Initializations this instance.
        /// </summary>
        public void Initialization()
        {
            InitLabels();
            FillDisplayVersionType();
        }

        /// <summary>
        /// Inits the labels.
        /// </summary>
        public override void InitLabels()
        {
            VersionModelLabel = Resx.GetLabel(ResxRioManager.VERSION_MODELTYPE_LABEL);
            ApprobalOptionLabel = Resx.GetLabel(ResxRioManager.VERSION_APPROBAL_OPTION_LABEL);
            StorageSpaceLabel = Resx.GetLabel(ResxRioManager.VERSION_STORAGE_SPACE);
            LastMajorMinorVersionsSaved = Resx.GetLabel(ResxRioManager.LAST_MAJOR_MINOR_VERSIONS_SAVED);
            LastMajorVersionsSaved = Resx.GetLabel(ResxRioManager.LAST_MAJOR_VERSIONS_SAVED);
            TabTitle = Resx.GetLabel(ResxRioManager.VERSIONING_MODEL_TAB);
            OrganizationLabel = Resx.GetLabel(ResxCommon.ORGANIZATION);
            FolderTypeLabel = Resx.GetLabel(ResxCommon.FOLDER_TYPE);
        }

        /// <summary>
        /// Determines whether this instance [can commit changes].
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance [can commit changes]; otherwise, <c>false</c>.
        /// </returns>
        private bool CanCommitChanges()
        {
            if (SelectedFolderType != null && SelectedFolderType.Identifier > 0)
                return true;
            else
                return false;
        }

        /// <summary>
        /// Change the description of the selected mode type
        /// </summary>
        private void ChangeLabelDescription()
        {
            switch (SelectedDisplayVersionType.Value)
            {
                case VersionType.None:
                    DescriptionLabel = Resx.GetLabel(ResxRioManager.VERSIONING_NONE);
                    IsUpDownVersionMajorEnabled = false;
                    IsUpDownVersionMinorEnabled = false;
                    break;

                case VersionType.NoControl:
                    DescriptionLabel = Resx.GetLabel(ResxRioManager.VERSION_LABEL_NOCONTROL);
                    IsUpDownVersionMajorEnabled = false;
                    IsUpDownVersionMinorEnabled = false;
                    break;

                case VersionType.Major:
                    DescriptionLabel = Resx.GetLabel(ResxRioManager.VERSION_LABEL_MAJOR);
                    IsUpDownVersionMajorEnabled = true;
                    IsUpDownVersionMinorEnabled = false;
                    break;

                case VersionType.MajorMinor:
                    DescriptionLabel = Resx.GetLabel(ResxRioManager.VERSION_LABEL_MAJORMINOR);
                    IsUpDownVersionMajorEnabled = true;
                    IsUpDownVersionMinorEnabled = true;
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void ClearModelValue()
        {
            this.SelectedModel = null;
            this.MaxMajorVersions = 0;
            this.MaxMinorVersions = 0;
            this.SelectedDisplayVersionType = Models.Where(item => item.Value == VersionType.None).FirstOrDefault();
        }

        /// <summary>
        /// Create a link with TypeDocument - Models
        /// </summary>
        /// <param name="l_oBEDomainContext">The l_o BE domain context.</param>
        private void CreateModel()
        {
            if (SelectedFolderType.Identifier > 0)
            {
                VersioningModel model = new VersioningModel();
                model.MaxMajorVersion = this.MaxMajorVersions;
                model.MaxMinorVersion = this.MaxMinorVersions;
                model.ModelType = this.SelectedDisplayVersionType.Value;
                model.WorkFlow = this.ApprovalWkfID;
                model.IsEnabled = true;

                BusyIndicator.Clear();
                BusyIndicator.AddBusyTask();

                BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();

                if (this.SelectedModel == null)
                {
                    //Create model
                    l_oBEDomainContext.SetVersionModel(
                        SelectedFolderType.Identifier,
                        model,
                        delegate(InvokeOperation retr)
                        {
                            //Get current model
                            GetModel();
                            BusyIndicator.RemoveBusyTask();

                            if (retr.Error == null)
                            {
                                MessageBox.Show(Resx.GetLabel(ResxRioManager.VERSIONING_COMMIT_SUCCESS));
                            }
                            else
                            {
                                MessageBox.Show(String.Format("{0}\n\t{1}", Resx.GetLabel(ResxRioManager.VERSIONING_COMMIT_SUCCESS), retr.Error.Message));
                            }
                        },
                        null);
                }
                else
                {
                    //Update an existing model only if
                    l_oBEDomainContext.HasCheckoutVersionByFolderType(
                        SelectedFolderType.Identifier,
                        delegate(InvokeOperation<ReturnBoolean> retr)
                        {
                            if (retr != null && retr.Value.IsValid && !retr.Value.Value)
                            {
                                //if (model.ModelType != SelectedModel.ModelType)
                                //{
                                //    //Set all versions to delete?
                                //}

                                model.Identifier = SelectedModel.Identifier;
                                l_oBEDomainContext.UpdateVersionModel(
                                    model, SelectedModel, SelectedFolderType.Identifier,
                                    delegate(InvokeOperation result)
                                    {
                                        BusyIndicator.RemoveBusyTask();

                                        if (result.Error == null)
                                        {
                                            MessageBox.Show(Resx.GetLabel(ResxRioManager.VERSIONING_COMMIT_SUCCESS));
                                        }
                                        else
                                        {
                                            MessageBox.Show(String.Format("{0}\n\t{1}", Resx.GetLabel(ResxRioManager.VERSIONING_COMMIT_SUCCESS), retr.Error.Message));
                                        }
                                    },
                                    null);
                            }
                            else
                            {
                                BusyIndicator.RemoveBusyTask();
                                MessageBoxChildWindow L_oMessageGetDocument = new MessageBoxChildWindow("Versioning", Resx.GetLabel(ResxRioManager.FOLDERTYPE_HAS_CHECHOUT), MessageBoxButtons.Ok, MessageBoxIcon.Warning);
                                L_oMessageGetDocument.Show();
                            }
                        }, null);

                }
            }
        }

        /// <summary>
        /// Bind Model list
        /// </summary>
        private void FillDisplayVersionType()
        {
            if (Models.Count == 0)
            {
                Models.Add(new DisplayVersionType(Resx.GetLabel(ResxRioManager.VERSIONING_NONE), VersionType.None));
                Models.Add(new DisplayVersionType(Resx.GetLabel(ResxRioManager.VERSIONING_NOCONTROL), VersionType.NoControl));
                Models.Add(new DisplayVersionType(Resx.GetLabel(ResxRioManager.VERSIONING_MAJOR), VersionType.Major));
                Models.Add(new DisplayVersionType(Resx.GetLabel(ResxRioManager.VERSIONING_MAJORMINOR), VersionType.MajorMinor));
            }
        }

        /// <summary>
        /// Get the model defintion for the current selected folder type
        /// </summary>
        private void GetModel()
        {
            if (SelectedFolderType != null && SelectedFolderType.Identifier > 0)
            {
                FillDisplayVersionType();

                BusyIndicator.Clear();
                BusyIndicator.AddBusyTask();

                BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();
                l_oBEDomainContext.GetVersionModel(
                    SelectedFolderType.Identifier,
                    delegate(InvokeOperation<List<VersioningModel>> retr)
                    {
                        if (retr.Error == null && retr.Value != null && retr.Value.Count > 0 && retr.Value.FirstOrDefault() != null)
                        {
                            this.SelectedModel = retr.Value.FirstOrDefault();

                            this.MaxMajorVersions = this.SelectedModel.MaxMajorVersion;
                            this.MaxMinorVersions = this.SelectedModel.MaxMinorVersion;
                            this.SelectedDisplayVersionType = Models.Where(item => item.Value == this.SelectedModel.ModelType).FirstOrDefault();
                            this.ApprovalWkfID = this.SelectedModel.WorkFlow;
                        }
                        else
                        {
                            ClearModelValue();
                        }

                        BusyIndicator.RemoveBusyTask();
                    },
                    null);
            }
        }

        #endregion Methods
    }
}